#include <iostream>
#include <mongo/client/dbclient.h>
#include "../util/util.h"
#include <sstream>
#define MAX_FILE_NAME_LEN 255
#define DOC_TERM_FILE "/data/lvhongliang/data/ask/2/mappedDocTerm.title.txt"
#define TERM_NUM 47088
#define AGE_ID "2"
using namespace std;
void saveToMongo(vector < vector<int> >& termDict, string mongodHost, string collectionName);
void printHelp()
{
    cout << "Usage: getReverseIndexAndStore -h mongodHost -i inputfile -n termNum -c collectionName" << endl;
}

int main(int argc, char* argv[])
{
    //get parameter
    const char *optstring = "h:i:n:c:";
    char docTermFile[MAX_FILE_NAME_LEN];
    int optch = 0;
    int termNum = 0, itemNum = 0, end = 0;
    string collectionName = "";
    string mongodHost = "";
    while ((optch = getopt(argc, argv, optstring)) != -1) {
        switch (optch) {
            case 'i':
                strcpy(docTermFile, optarg);
                break;
            case 'n':
                termNum = atoi(optarg);
                break;
            case 'c':
                collectionName = optarg;
                break;
            case 'h':
                mongodHost = optarg;
                break;
            default:
                printHelp();
                return 1;
        }
    }
    if (0 == termNum || "" == collectionName || "" == mongodHost || strlen(docTermFile) < 1) {
        printHelp();
        return 1;
    }
    //1. load the doc-term matrix
    std::ifstream from;
    from.open(docTermFile, ios_base::in);
    if (!from.is_open()) {
        cout << "can't open input file:" << docTermFile << "!\n";
        exit(1);
    }
    char rateStr[100];
    char* pch;
    int docId=0, termId=0;
    vector< vector<int> > termDict(termNum+1); while (!from.eof()) {
        from.getline(rateStr, 100);
        if (strlen(rateStr) < 3)continue;
        pch = strtok (rateStr, " ");
        if (pch != NULL) {
            docId = atoi(pch);
        }
        pch = strtok (NULL, " ");
        termId = atoi(pch);
        //cout << docId << '\t' << termId << endl;
        termDict[termId].push_back(docId);
        ++itemNum;
    }
    from.close();
    cout << "Read " << itemNum << " records!" << endl;

    typedef vector<int>::const_iterator Iter;
    //2. for every term, store the key value to mongoDB
    saveToMongo(termDict, mongodHost, collectionName);        
}

void saveToMongo(vector < vector<int> >& termDict, string mongodHost, string collectionName)
{
    typedef vector<int>::iterator Iter;
    mongo::DBClientConnection c;
    c.connect(mongodHost); 
    mongo::BSONObj p;
    int vectorSize = termDict.size();
    for (int i=1; i< vectorSize; ++i) {
        Iter it = termDict[i].begin();
        //ostringstream os;
        //os << "[";
        mongo::BSONArrayBuilder b;
        sort(termDict[i].begin(), termDict[i].end());
        for (; it != termDict[i].end(); ++it) {
            //if (it == termDict[i].begin()) os << *it;
            //else os << "," << *it;
            b.append(*it);
        }
        //os << "]";
        //string tmpStr = os.str();
        //p = BSON( "id" << i << "relatedDoc" << tmpStr);
        p = BSON( "id" << i << "relatedDoc" << b.arr());
        c.insert(collectionName, p);
    }
}
